use std::borrow::BorrowMut;
use std::sync::{Arc, RwLock};

pub struct queue<T> {
    inner:Arc<RwLock<Vec<T>>>,
}

impl<T> queue<T> where T : Clone {
    pub fn new() -> Self {
        let mut v = Vec::new();
        let mut q = queue{
            inner:Arc::new(RwLock::new(v)),
        };

        q
    }
}

impl<T> queue<T> where T : Clone {
    pub fn push(&mut self,data:T) ->Result<(),String> {
        let res = self.inner.write();
        if let Err(e) = res {
            return Err(e.to_string());
        }

        res.unwrap().push(data);
        Ok(())
    }

    pub fn pop(&mut self) -> Result<T,String> {
        let res= self.inner.read();
        if let Err(e) = res {
            return Err(e.to_string());
        }

        let old = res.unwrap().clone();
        let first = old.first().unwrap();

        let (_,new) = old.split_at(1);
        *self.inner.write().unwrap() = new.to_vec();

        Ok(first.clone())
    }

    pub fn len(&self) -> usize {
        match self.inner.read() {
            Ok(data) => {
                data.len()
            },
            Err(e)=> {
                0
            }
        }
    }
}

#[cfg(test)]
mod test  {
    use crate::queue::queue;

    #[test]
    fn test() {
        let mut q = queue::new();
        q.push("啊啊啊").unwrap();
        q.push("噢噢噢").unwrap();
        println!("{}",q.len());

        let res = q.pop();
        match res {
            Ok(a) => {println!("{}",a)}
            Err(e) => {println!("{}",e)}
        }
        println!("{:?}",q.inner);
    }
}